package cz.muni.fi.pb138.jaro2011.uloha1;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/*************************************************************************
 *  Take this skeleton code and implement the missing body of
 *  <code>changeName</code>, <code>getWageCosts</code>, and
 *  <code>removeCarsProducedEarlierThan</code> methods.
 *  Everything else should be left untouched.<br/>
 * 
 *  After completion, the <code>main</code> method should work correctly.<br/>
 * 
 *  You may use either NetBeans or Ant build.xml to compile and run it.
 */
public class Main {

    /**
     * W3C object model representation of a XML document.
     * Note: We use the interface(!) not its implementation
     */
    private Document doc;

    /*************************************************************************
     * Method changing the salary of a person owning a car with the given
     * <code>carId</code> by subtracting the given <code>fine</code> from
     * this person's salary. There is just one car with a given carId,
     * so be effective...
     * 
     * Other persons should not be affected.
     */
    public void reduceSalaryByFine(final String carId, final double fine) {
        // complete the code
    }

    /*************************************************************************
     * This method calculates the average age of all the cars.
     * Hint: Iterate over all cars ages (in the year elements)
     * in the file and calculate the sum of them.
     * Then, divide it by the number of cars and return it.
     * (The XML document must not be modified anyhow by this method.)
     * @return the average age of all cars in the document
     */
    public double getAverageCarAge() {
        return 0.0; // delete this line and complete the code
    }

    /** 
     * Removes cars produced in the given year
     * and returns the count of cars removed.
     * 
     * @param year the year 
     * @return the count of cars removed
     */
    public int removeCarsProducedIn(int year) {
        return 0; // delete this line and complete the code
    }

    /*************************************************************************/
    /**
     * Vytvori novou instanci teto tridy a nacte obsah
     * xml dokumentu se zadanym URL.
     */
    public static Main newInstance(URI uri) throws SAXException,
            ParserConfigurationException, IOException {
        return new Main(uri);
    }

    /**
     * Create a new instance of this class and read the content 
     * of the given XML file.
     */
    public static Main newInstance(File file)
            throws SAXException, ParserConfigurationException, IOException {
        return newInstance(file.toURI());
    }

    /**
     * Constructor creating a new instance of Uloha1 class
     * reading from the file at the given URI
     */
    private Main(URI uri) throws SAXException, ParserConfigurationException,
            IOException {
        // Vytvorime instanci tovarni tridy
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // Pomoci tovarni tridy ziskame instanci DocumentBuilderu
        DocumentBuilder builder = factory.newDocumentBuilder();
        // DocumentBuilder pouzijeme pro zpracovani XML dokumentu
        // a ziskame model dokumentu ve formatu W3C DOM
        doc = builder.parse(uri.toString());
    }

    public void serializetoXML(URI output)
            throws IOException, TransformerConfigurationException, TransformerException {
        // Vytvorime instanci tovarni tridy
        TransformerFactory factory = TransformerFactory.newInstance();
        // Pomoci tovarni tridy ziskame instanci tzv. kopirovaciho transformeru
        Transformer transformer = factory.newTransformer();
        // Vstupem transformace bude dokument v pameti
        DOMSource source = new DOMSource(doc);
        // Vystupem transformace bude vystupni soubor
        StreamResult result = new StreamResult(output.toString());
        // Provedeme transformaci
        transformer.transform(source, result);
    }

    public void serializetoXML(File output) throws IOException,
            TransformerException {
        serializetoXML(output.toURI());
    }

    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException, TransformerException {

        if (args.length < 1) {
            System.err.println("Chybi argument se jmenem souboru pro "
                    + "zpracovani!");
            return;
        } else if (args.length < 2) {
            System.err.println("Chybi argument se jmenem vystupniho souboru!");
            return;
        }

        File input = new File(args[0]);
        File output = new File(args[1]);

        Main uloha1 = newInstance(input);

        System.out.println(uloha1.getAverageCarAge());

        uloha1.reduceSalaryByFine("6B6 82-51", 20000.0);
        uloha1.reduceSalaryByFine("ZNC 33-93", 1000.0);

        int carsRemoved = uloha1.removeCarsProducedIn(2001);

        System.out.println("Removed " + carsRemoved + " cars older than 2001.");

        uloha1.serializetoXML(output);
    }

    /**
     * Help method for testing purposes.
     */
    Document getDocument() {
        return doc;
    }
}
